# -*- coding: utf-8 -*-
# @Time    : 2024/9/27 14:49
# @Author  : Alvin
# @File    : SyncOrderLanShouImpl.py
# @Des     : 同步单揽收实现类
import logging
import time
import traceback
from typing import List
from concurrent.futures import ThreadPoolExecutor
import jsonpath

from handler.BaseLogisticsImpl import BaseLogisticsImpl
from model.LanShouModel import LanShouModel
from utils import CommonUtil, CheUtil
from utils.DatabaseHandler import DatabaseHandler

import json
import requests


class SyncOrderLanShouImpl(BaseLogisticsImpl):

    def __init__(self):
        super(SyncOrderLanShouImpl, self).__init__()
        self.need_lanshou_list = []
        self.log_text = "同步单揽收任务"
        self.max_workers = 7

    def start_handle_dy_lanshou_task(self, batch_index, db_data_list: List[LanShouModel]):
        """
        开始处理揽收任务
        :param batch_index:
        :param db_data_list:
        :return:
        """
        try:
            is_login = self.check_user_is_logined()
            if not is_login:
                logging.error("用户登录失败，请检查登录数据是否异常")
                return
            with ThreadPoolExecutor(max_workers=self.max_workers) as pool:
                for item in db_data_list:
                    pool.submit(self.handle_sync_lan_shou_action, item)
            logging.info(f"第【{batch_index}】数据跑完了，共需更新:{len(self.need_lanshou_list)}条数据")
            self.db_util.update_sync_order_lanshou_info(self.need_lanshou_list)
        except Exception as ex:
            logging.error(f"【start_handle_dy_lanshou_task】异常:{str(ex)}")
            logging.error(f"【start_handle_dy_lanshou_task】异常2:%s", traceback.format_exc())

    def handle_sync_lan_shou_action(self, dbItem: LanShouModel):
        try:
            code, name = self.query_express_code(dbItem.mailNo)
            if not code:
                logging.info(f"[{dbItem.mailNo}]未查询到上家物流公司编号")
            else:
                logisticsResp = self.queryLogisticsInfoByKuaiDi100(dbItem.mailNo, code)
                if not logisticsResp:
                    return
                self.handleLogisticsResponseInfo(dbItem, logisticsResp)
        except Exception as ex:
            logging.error(f"【handle_sync_lan_shou_action】异常:{str(ex)}")
            logging.error(f"【handle_sync_lan_shou_action】异常2:%s", traceback.format_exc())

    def start_handle_data_lanshou_action(self, data_list):
        try:
            logging.info(f"【{self.log_text}】数据跑完了：{len(self.need_lanshou_list)}")
            if not self.need_lanshou_list:
                logging.info(f"【{self.log_text}】需要更新数量为0,本次查询数量为：{len(data_list)}")
            else:
                try:
                    newList = CommonUtil.quChong(self.need_lanshou_list)
                except Exception as ex:
                    newList = self.need_lanshou_list
                    logging.error(f"【{self.log_text}】数据去重异常2:%s", str(ex))
                    logging.error(f"【{self.log_text}】数据去重异常:%s", traceback.format_exc())
                lanshouList = CommonUtil.splitList(newList, 800)
                for lis in lanshouList:
                    DatabaseHandler().update_sync_order_lanshou_info(lis)
                    time.sleep(1)
        except Exception as ex:
            logging.error(f"【{self.log_text}】异常:{str(ex)}")
            logging.error(f"【{self.log_text}】异常2:%s", traceback.format_exc())

    # 处理快递100响应数据
    def handleLogisticsResponseInfo(self, dbItem, resp_data):
        try:
            if 'data' in resp_data and len(resp_data['data']) > 0:
                logisticsList = resp_data['data']
                if not logisticsList:
                    logging.info(f"【{self.log_text}】信息返回为空：{resp_data['message']},上家单号：{dbItem.mailNo}")
                else:
                    self.handle_complete_peizai(dbItem)
            else:
                logging.info(f"【{self.log_text}】快递信息返回为空：{resp_data['message']},上家单号：{dbItem.mailNo}")
        except Exception as ex:
            logging.error(f"【{self.log_text}】快递信息异常：{str(ex)},上家单号->{dbItem.mailNo},车氏物流单号->{dbItem.mailNo_self}")
            logging.error(f"【{self.log_text}】快递信息异常:%s", traceback.format_exc())

    def handle_complete_peizai(self, dbItem: LanShouModel):
        order_data = self.get_order_detail(dbItem.mailNo_self)
        if not order_data:
            return
        pz_param = self.get_pei_zai_param(order_data)
        url = "https://apit9.lqfast.com/lanqiao-tms-app/web/outgoingRegistration/saveSingleMiddle"
        headers = CheUtil.get_request_header(self.token, self.requestToken)
        data = {
            "m": "func",
            "n": "saveSingleMiddle",
            "p": {
                "jsonStr": json.dumps(pz_param),
                "ismodify": 0,
                "ingettype": 0,
                "isconfirm": 0,
                "isKZ": 0
            },
            "l": "",
            "v": "",
            "u": CheUtil.get_param_u(self.token),
            "r": "k",
            "s": "k",
            "t": int(time.time() * 1000)
        }
        data = json.dumps(data, separators=(',', ':'))
        resp_json = requests.post(url, headers=headers, data=data).json()
        resp_status = resp_json.get("success")
        if not resp_status:
            logging.error(f"完成配载失败，接口响应：{resp_json}")
            return
        needUpdateParam = {
            "id": dbItem.id,
            "statusCode": 'GOT',
            "statusStr": "已揽收",
            "logisticsInfo": "您的包裹已由物流公司揽收",
            "expressLastUpdateTime": CommonUtil.get_current_format_time(),
            "updateTime": CommonUtil.get_current_format_time()
        }
        self.need_lanshou_list.append(needUpdateParam)

    def get_pei_zai_param(self, order_detail, city='广州', des='您的包裹已由物流公司揽收'):
        """

        @param order_detail:
        @param city:
        @param des: 快递描述
        @return:
        """
        param = {
            "midd_dw": city,  # 中转城市
            "midd_date": CommonUtil.get_current_format_time(),
            "midd_stel": "",
            "midd_etel": "",
            "midd_adrr": "",
            "midd_unit": "",
            "midd_willdate": "",
            "midd_price": 0,
            "midd_price_payState": True,
            "s_midd_price": 0,
            "s_midd_price_payState": False,
            "midd_bz_price": 0,
            "midd_zz_outacctrans": 0,
            "midd_zx_price": 0,
            "midd_cc_price": 0,
            "midd_youkahao": "",
            "midd_youka_price": 0,
            "midd_other_price": 0,
            "midd_explain": "",
            "midd_remark": des,
            "midd_modifyremark": "",
            "outappremarks": "",
            "outadvance": "0",
            "isShipperSms": False,
            "isConsigneeSms": False,
            "outacc_c": 0,
            "ck_price": 0,
            "acctype": "月结",
            "accsend": 0,
            "acctrans": 0,
            "outacctype": "",
            "unit": order_detail.get("unit"),
            "outtype": "",
            "esite": "苏州市",
            "accnowold": 0,
            "accbackold": 0,
            "accmonthold": 0,
            "acchuikou": 0,
            "outmadeby": order_detail.get("outmadeby"),
            "outcompanyid": "",
            "type": "添加",
            "outunit": 0,
            "vipno": "",
            "billno": order_detail.get("billno"),
            "shipper": order_detail.get("shipper"),
            "consignee": order_detail.get("consignee"),
            "bsite": order_detail.get("bsite"),
            "qty": order_detail.get("qty"),
            "product": order_detail.get("product"),
            "shippermb": order_detail.get("shippermb"),
            "shippertel": "",
            "weight": 0,
            "volumn": 0,
            "consigneetel": "",
            "consigneemb": order_detail.get("consigneemb"),
            "canprint": False,
            "canmodify": True,
            "middlesite": "",
            "addr": order_detail.get("addr"),
            "state": 0,
            "middle_webname": "",
            "middle_paytype": "",
            "outweight": 0,
            "outvolumn": 0,
            "billremake": "",
            "accarrivedold": 0,
            "billdate": order_detail.get("billdate"),
            "outWeightWT": None,
            "outVolumnWT": None,
            "outcygsid": 0
        }
        return param
